package org.formal.common.service;

import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import org.apache.commons.lang3.StringUtils;
import org.formal.common.base.BaseDao;
import org.formal.common.base.BaseEntity;
import org.formal.common.base.BaseService;
import org.formal.common.utils.DateUtils;
import org.formal.system.shiro.manager.TokenManager;
import org.springframework.beans.factory.annotation.Autowired;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

/**
 * service基础方法实现类
 * @version:1.0
 * @Description: BaseServiceImpl
 * @author: jiangyan 
 * @date: 2018年9月20日
 */
public abstract class BaseServiceImpl<T extends BaseEntity> implements BaseService<T> {
	
	@SuppressWarnings("unchecked")
	private Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
	.getActualTypeArguments()[0];
	
	/**
	 * 默认字段  是否删除
	 */
	private final String IS_DELETE = "isDelete";
	
	/**
	 * 默认值 0 否 1 是
	 */
	private final String DELETE_VALUE = "0";
	
	@Autowired
	protected BaseDao<T> baseDao;
	
	public BaseDao<T> getbaseDao() {
		return baseDao;
	}
	
	/**
	 * 根据主键id 查询实体
	 */
	@Override
	public T selectByKey(Object key) {
		return baseDao.selectByPrimaryKey(key);
	}
	
	/**
	 * 查询所有未被删除的实体数据
	 */
	@Override
	public List<T> selectAll() {
		Example example = new Example(entityClass);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo(IS_DELETE, DELETE_VALUE);
		List<T> list = baseDao.selectByExample(example);
		return list;
	}
	
	/**
	 * 根据map查询实体数据  使用=进行匹配
	 */
	@Override
	public List<T> selectByExample(Map<String, Object> map) {
		Example example = new Example(entityClass);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo(IS_DELETE, DELETE_VALUE);
		if(map != null && !map.isEmpty()) {
			criteria.andAllEqualTo(map);
		}
		List<T> list = baseDao.selectByExample(example);
		return list;
	}
	
	/**
	 * 根据example查询实体数据 可以自定义条件匹配
	 */
	@Override
	public List<T> selectByExample(Object example) {
		return baseDao.selectByExample(example);
	}
	
	/**
	 * 根据id 是否存在保存或者修改不为空的项 
	 * 空字符会修改  空值是null 不会修改
	 */
	@Override
	public int save(T entity) {
		int result = 0;
		this.setEntityInfo(entity);
		try {
			Class<?> clazz = entity.getClass().getSuperclass();
			Field field = clazz.getDeclaredField("id");
			field.setAccessible(true);
			Object value = field.get(entity);
			if (value == null || value == "") {
				String uuId = UUID.randomUUID().toString().replace("-", "");
				field.set(entity, uuId);
				result = baseDao.insertSelective(entity);
			} else {
				result = baseDao.updateByPrimaryKeySelective(entity);
			}
		} catch (NoSuchFieldException e) {
			System.out.println("字段id未找到");
			e.printStackTrace();
		} catch (SecurityException e) {
			System.out.println("没有权限访问");
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 设置实体的创建时间、创建人、等默认属性
	 * @param entity
	 */
	public void setEntityInfo(BaseEntity entity) {
		if (StringUtils.isBlank(entity.getId())) {
			entity.setId(null);
			entity.setCreateTime(DateUtils.getCurDateTime());
			entity.setIsDelete(false);
			entity.setCreateUser(TokenManager.getLoginName());
		}
		entity.setLastUpdateTime(DateUtils.getCurDateTime());
		entity.setLastUpdateUser(TokenManager.getUserId());
	}
	
	/**
	 * 根据主键id删除实体 返回 1 删除成功  0删除失败
	 */
	@Override
	public int delete(Object key) {
		return baseDao.deleteByPrimaryKey(key);
	}
	/**
	 * 根据实体数据全部修改（包含空） 返回 1 删除成功  0删除失败
	 */
	@Override
	public int updateAll(T entity) {
		return baseDao.updateByPrimaryKey(entity);
	}
	/**
	 * 根据实体数据全部修改（不包含空） 返回 1 删除成功  0删除失败
	 */
	@Override
	public int updateNotNull(T entity) {
		return baseDao.updateByPrimaryKeySelective(entity);
	}
	
	/**
	 * 根据实体数据查询合计数
	 */
	@Override
	public int selectCount(T entity) {
		return baseDao.selectCount(entity);
	}
	
	/***
	* 驼峰命名转为下划线命名
	 * @param sort 
	 * 
	 * @param para
	 *        驼峰命名的字符串
	 */

    public String humpToUnderline(String param, String sort){
            StringBuilder sb=new StringBuilder(param);
            int temp = 0;
            for(int i=0;i<param.length();i++){
                if(Character.isUpperCase(param.charAt(i))){
                    sb.insert(i+temp, "_");
                    temp+=1;
                }
            }
            sb.append(" ").append(sort);
            return sb.toString(); 
    }
}
